package com.gxa.ehome.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

//要实现一个切面编程,需要两个注解配合:
@Component
@Aspect
public class LogAspect {

    // 设置切点: 动态增强的位置(方法)
    // 自动记录业务操作的日志: 所有的Service的方法
    // 自动为所有的业务层添加事务: 事务开始(关闭自动提交)/在异常的时候事务回滚/在没有异常的时候事务提交/在finally中回收SqlSession(close)

    /*找到任意访问权限任意返回值,
    * Integer com.gxa.ehome.service.SysUserService.*(int.)
    在service包中的类的所有方法
    无论什么参数结构*/
    @Pointcut("execution(* com.gxa.ehome.service.*.*(..))")
    public void pointCut(){}

    //前置通知
    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        joinPoint.getArgs();  // 获取参数信息
        joinPoint.getTarget(); // 获取代理目标
        System.out.println("这是一个前置通知, Before");
    }

    //后置返回通知
    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("这是一个后置返回通知, AfterReturning");
    }

    //后置抛出通知
    @AfterThrowing("pointCut()")
    public void afterThrowing(){
        System.out.println("这是一个后置返回通知, AfterThrowing");
    }

    //后置通知
    @After("pointCut()")
    public void after(){
        System.out.println("这是一个后置返回通知, After");
    }

    // 环绕通知, 相当于将上述四种通知组合在一起使用
    // 环绕通知不能和其他四个合用
   /* @Around("pointCut()")
    public void around(ProceedingJoinPoint joinPoint){

        try {
            System.out.println("前置通知");
            joinPoint.proceed(); // 代理方法的执行位置
            System.out.println("后置返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("后置抛出通知");
        }finally{
            System.out.println("后置通知");
        }
    }*/
}
